const log = require('electron-log')
const { defaultSetting, overwriteSetting } = require('./defaultSetting')
// const apiSource = require('../renderer/utils/music/api-source-info')

exports.isLinux = process.platform === 'linux'
exports.isWin = process.platform === 'win32'
exports.isMac = process.platform === 'darwin'

/**
 * 生成节流函数
 * @param {*} fn
 * @param {*} delay
 */
exports.throttle = (fn, delay = 100) => {
  let timer = null
  let _args = null
  return function (...args) {
    _args = args
    if (timer) return
    timer = setTimeout(() => {
      timer = null
      fn.apply(this, _args)
    }, delay)
  }
}

/**
 * 生成防抖函数
 * @param {*} fn
 * @param {*} delay
 */
exports.debounce = (fn, delay = 100) => {
  let timer = null
  let _args = null
  return function (...args) {
    _args = args
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      timer = null
      fn.apply(this, _args)
    }, delay)
  }
}

exports.log = log

// https://stackoverflow.com/a/53387532
exports.compareVer = (currentVer, targetVer) => {
  // treat non-numerical characters as lower version
  // replacing them with a negative number based on charcode of each character
  const fix = s => `.${s.toLowerCase().charCodeAt(0) - 2147483647}.`

  currentVer = ('' + currentVer).replace(/[^0-9.]/g, fix).split('.')
  targetVer = ('' + targetVer).replace(/[^0-9.]/g, fix).split('.')
  const c = Math.max(currentVer.length, targetVer.length)
  for (let i = 0; i < c; i++) {
    // convert to integer the most efficient way
    currentVer[i] = ~~currentVer[i]
    targetVer[i] = ~~targetVer[i]
    if (currentVer[i] > targetVer[i]) return 1
    else if (currentVer[i] < targetVer[i]) return -1
  }
  return 0
}

exports.isObject = item => item && typeof item === 'object' && !Array.isArray(item)

/**
 * 对象深度合并
 * @param  {} target 要合并源对象
 * @param  {} source 要合并目标对象
 */
exports.objectDeepMerge = (target, source, mergedObj) => {
  if (!mergedObj) {
    mergedObj = new Set()
    mergedObj.add(target)
  }
  const base = {}
  Object.keys(source).forEach(item => {
    if (exports.isObject(source[item])) {
      if (mergedObj.has(source[item])) return
      if (!exports.isObject(target[item])) target[item] = {}
      mergedObj.add(source[item])
      exports.objectDeepMerge(target[item], source[item], mergedObj)
      return
    }
    base[item] = source[item]
  })
  Object.assign(target, base)
}

exports.mergeSetting = (setting, version) => {
  const defaultSettingCopy = JSON.parse(JSON.stringify(defaultSetting))
  const overwriteSettingCopy = JSON.parse(JSON.stringify(overwriteSetting))
  const defaultVersion = defaultSettingCopy.version
  if (!version) {
    if (setting) {
      version = setting.version
      delete setting.version
    }
  }

  if (!setting) {
    setting = defaultSettingCopy
  } else if (exports.compareVer(version, defaultVersion) < 0) {
    exports.objectDeepMerge(defaultSettingCopy, setting)
    exports.objectDeepMerge(defaultSettingCopy, overwriteSettingCopy)
    setting = defaultSettingCopy
  }

  // if (!apiSource.some(api => api.id === setting.apiSource && !api.disabled)) {
  //   let api = apiSource.find(api => !api.disabled)
  //   if (api) setting.apiSource = api.id
  // }

  return { setting, version: defaultVersion }
}
